﻿using System;
using System.Reflection;
using Evolution.Application.SharedKernel.Actions;
using Evolution.Application.SharedKernel.Actions.Parameters;
using Evolution.Client.ImportData.Infrastructure;
using Evolution.Sdk.Commands;
using Evolution.Sdk.DataObjects;
using Microsoft.Practices.Unity;

namespace Evolution.Client.ImportData.Actions
{
    public abstract class SendCommandToBus : ImportInfrastructure
    {
        protected IAction<TAnyActionParameters> ResolveAction<TAnyActionParameters>() where TAnyActionParameters : IActionParameters
        {
            return base.Resolve<IAction<TAnyActionParameters>>(new ResolverOverride[0]);
        }

        /// <summary>
        /// Invoke SendDataObjectCommand with dataObject is generic type
        /// </summary>
        /// <param name="objectType"></param>
        /// <param name="dataObject"></param>
        protected void SendDataObjectCommand(Type objectType, object dataObject)
        {
            if(dataObject is DataObject)
            {
                // Get Method Information.
                MethodInfo myMethodInfo = this.GetType().GetMethod("SendDataObjectCommand");
                object[] mParam = new object[] { dataObject };
                MethodInfo genericMethod = myMethodInfo.MakeGenericMethod(new Type[] { objectType });
                // Invoke method.
                genericMethod.Invoke(this, mParam);
            }
            else if(dataObject is AbstractAggregateCommand)
            {
                SendAggregateCommand((ICommand)dataObject);
            }
        }

        public void SendDataObjectCommand<TDataObject>(TDataObject dataObject) where TDataObject : DataObject
        {
            DataObjectCommand<TDataObject> command = new DataObjectCommand<TDataObject>(dataObject.Id, dataObject)
            {
                Header = { CorrelationId = new Guid?(Guid.Empty) }
            };
            base.Resolve<ICommandBus>(new ResolverOverride[0]).SendCommand<DataObjectCommand<TDataObject>>(command);
        }

        public void SendAggregateCommand(ICommand command)
        {
            var commandBus = this.Resolve<ICommandBus>();
            commandBus.SendCommand(command);
        }
    }

 

}